// import com.alibaba.druid.sql.ast.*;
// import com.alibaba.druid.sql.visitor.SQLASTVisitor_ptr;

// import java.util.ArrayList;
// import java.util.List;

#include "SQLIfStatement.h"
#include "../../visitor/SQLASTVisitor.h"
#include "../../../utils/listTran.h"

SQLIfStatement_ElseIf::SQLIfStatement_ElseIf()
{
  statements = std::make_shared<std::list<SQLStatement_ptr>>();
}

// @Override
void SQLIfStatement_ElseIf::accept0(SQLASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(SQLIfStatement_ElseIf)))
  {
    acceptChild(visitor, condition);
    SQLObject_list_ptr tmp = ListTran::tran_class<SQLStatement, SQLObject>(statements);
    acceptChild(visitor, tmp);
  }
  visitor->endVisit(SharedObject(SQLIfStatement_ElseIf));
}

SQLStatement_list_ptr SQLIfStatement_ElseIf::getStatements()
{
  return statements;
}

void SQLIfStatement_ElseIf::setStatements(SQLStatement_list_ptr statements)
{
  this->statements = statements;
}

SQLExpr_ptr SQLIfStatement_ElseIf::getCondition()
{
  return condition;
}

void SQLIfStatement_ElseIf::setCondition(SQLExpr_ptr condition)
{
  if (condition != nullptr)
  {
    condition->setParent(SharedObject(SQLIfStatement_ElseIf));
  }
  this->condition = condition;
}

// @Override
BOOL_ptr SQLIfStatement_ElseIf::replace(SQLExpr_ptr expr, SQLExpr_ptr target)
{
  if (condition == expr)
  {
    setCondition(target);
    return BOOL::TRUE;
  }

  return BOOL::FALSE;
}

SQLObject_ptr SQLIfStatement_ElseIf::clone()
{
  SQLObject_ptr clone_tmp = std::shared_ptr<SQLIfStatement_ElseIf>(new SQLIfStatement_ElseIf());
  std::shared_ptr<SQLIfStatement_ElseIf> x = std::dynamic_pointer_cast<SQLIfStatement_ElseIf>(clone_tmp);
  // SQLIfStatement_ElseIf x = new SQLIfStatement_ElseIf();

  if (condition != nullptr)
  {
    x->setCondition(std::dynamic_pointer_cast<SQLExpr>(condition->clone()));
  }
  for (SQLStatement_ptr stmt : *statements)
  {
    SQLStatement_ptr stmt2 = std::dynamic_pointer_cast<SQLStatement>(stmt->clone());
    stmt2->setParent(x);
    x->statements->push_back(stmt2);
  }

  return x;
}

SQLIfStatement_Else::SQLIfStatement_Else()
{
  statements = std::make_shared<std::list<SQLStatement_ptr>>();
}
// @Override
void SQLIfStatement_Else::accept0(SQLASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(SQLIfStatement_Else)))
  {
    SQLObject_list_ptr tmp = ListTran::tran_class<SQLStatement, SQLObject>(statements);
    acceptChild(visitor, tmp);
  }
  visitor->endVisit(SharedObject(SQLIfStatement_Else));
}

SQLStatement_list_ptr SQLIfStatement_Else::getStatements()
{
  return statements;
}

void SQLIfStatement_Else::setStatements(SQLStatement_list_ptr statements)
{
  this->statements = statements;
}

SQLObject_ptr SQLIfStatement_Else::clone()
{
  SQLObject_ptr clone_tmp = std::shared_ptr<SQLIfStatement_Else>(new SQLIfStatement_Else());
  std::shared_ptr<SQLIfStatement_Else> x = std::dynamic_pointer_cast<SQLIfStatement_Else>(clone_tmp);
  // SQLIfStatement_Else x = new SQLIfStatement_Else();
  for (SQLStatement_ptr stmt : *statements)
  {
    SQLStatement_ptr stmt2 = std::dynamic_pointer_cast<SQLStatement>(stmt->clone());
    stmt2->setParent(x);
    x->statements->push_back(stmt2);
  }
  return x;
}

SQLIfStatement::SQLIfStatement()
{
  statements = std::make_shared<std::list<SQLStatement_ptr>>();
  elseIfList = std::make_shared<std::list<SQLIfStatement_ElseIf_ptr>>();
}
SQLObject_ptr SQLIfStatement::clone()
{
  SQLObject_ptr clone_tmp = std::shared_ptr<SQLIfStatement>(new SQLIfStatement());
  std::shared_ptr<SQLIfStatement> x = std::dynamic_pointer_cast<SQLIfStatement>(clone_tmp);
  // SQLIfStatement x = new SQLIfStatement();

  for (SQLStatement_ptr stmt : *statements)
  {
    SQLStatement_ptr stmt2 = std::dynamic_pointer_cast<SQLStatement>(stmt->clone());
    stmt2->setParent(x);
    x->statements->push_back(stmt2);
  }
  for (SQLIfStatement_ElseIf_ptr o : *elseIfList)
  {
    SQLIfStatement_ElseIf_ptr o2 = std::dynamic_pointer_cast<SQLIfStatement_ElseIf>(o->clone());
    o2->setParent(x);
    x->elseIfList->push_back(o2);
  }
  if (elseItem != nullptr)
  {
    x->setElseItem(std::dynamic_pointer_cast<SQLIfStatement_Else>(elseItem->clone()));
  }

  return x;
}

// @Override
void SQLIfStatement::accept0(SQLASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(SQLIfStatement)))
  {
    if (condition != nullptr)
    {
      condition->accept(visitor);
    }

    auto it_statements = statements->begin();
    for (int i = 0; i < statements->size(); i++)
    {
      std::advance(it_statements, i);
      (*it_statements)->accept(visitor);
    }

    auto it_elseIfList = elseIfList->begin();
    for (int i = 0; i < elseIfList->size(); i++)
    {
      std::advance(it_elseIfList, i);
      (*it_elseIfList)->accept(visitor);
    }

    if (elseItem != nullptr)
    {
      elseItem->accept(visitor);
    }
  }
  visitor->endVisit(SharedObject(SQLIfStatement));
}

SQLExpr_ptr SQLIfStatement::getCondition()
{
  return condition;
}

void SQLIfStatement::setCondition(SQLExpr_ptr condition)
{
  if (condition != nullptr)
  {
    condition->setParent(SharedObject(SQLIfStatement));
  }
  this->condition = condition;
}

SQLStatement_list_ptr SQLIfStatement::getStatements()
{
  return statements;
}

void SQLIfStatement::addStatement(SQLStatement_ptr statement)
{
  if (statement != nullptr)
  {
    statement->setParent(SharedObject(SQLIfStatement));
  }
  this->statements->push_back(statement);
}

SQLIfStatement_ElseIf_list_ptr SQLIfStatement::getElseIfList()
{
  return elseIfList;
}

SQLIfStatement_Else_ptr SQLIfStatement::getElseItem()
{
  return elseItem;
}

void SQLIfStatement::setElseItem(SQLIfStatement_Else_ptr elseItem)
{
  if (elseItem != nullptr)
  {
    elseItem->setParent(SharedObject(SQLIfStatement));
  }
  this->elseItem = elseItem;
}

// @Override
BOOL_ptr SQLIfStatement::replace(SQLExpr_ptr expr, SQLExpr_ptr target)
{
  if (condition == expr)
  {
    setCondition(target);
    return BOOL::TRUE;
  }

  return BOOL::FALSE;
}
